package com.ffcs.crmd.tsp.task.job;

import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;

import org.slf4j.Logger;

import com.ffcs.crmd.tsp.api.task.job.IJobBatch;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.task.log.TaskLogger;

/**
 * 
 * 功能说明:业务数据处理线程
 *
 * @author ZHONGFUHUA
 * 
 * @since 1.0.0-SNAPSHOT
 *
 */
public class BusinessProcessor<T> implements Runnable {
    
    /**
     * 日志
     */
    private static final Logger                         LOG = TaskLogger.getLogger(LoggerName.TaskLoggerName);
    
    /**
     * 子线程任务参数
     */
    private T                                           businessData;
    
    /**
     * 完成子任务锁
     */
    private Lock                                        completeLock;
    
    /**
     * 返回等待对象
     */
    private CountDownLatch                              returnWaitting;
    
    /**
     * 任务实例
     */
    private IJobBatch<T>                                jobInstance;
    
    /**
     * 任务实例
     */
    @SuppressWarnings("deprecation")
    private com.ffcs.crmd.tsp.task.job.api.IJobBatch<T> jobInstanceOld;
    
    /**
     * 批量业务数据处理线程集合
     */
    private Map<BusinessProcessor<T>, T>                businessProcessThreadMap;
    
    public BusinessProcessor(IJobBatch<T> jobInstance, T businessData, Map<BusinessProcessor<T>, T> businessProcessThreadMap, Lock completeLock,
        CountDownLatch returnWaitting) {
        this.businessData = businessData;
        this.jobInstance = jobInstance;
        this.completeLock = completeLock;
        this.returnWaitting = returnWaitting;
        this.businessProcessThreadMap = businessProcessThreadMap;
    }
    
    @SuppressWarnings("deprecation")
    public BusinessProcessor(com.ffcs.crmd.tsp.task.job.api.IJobBatch<T> jobInstance, T businessData,
        Map<BusinessProcessor<T>, T> businessProcessThreadMap, Lock completeLock, CountDownLatch returnWaitting) {
        this.businessData = businessData;
        this.jobInstanceOld = jobInstance;
        this.completeLock = completeLock;
        this.returnWaitting = returnWaitting;
        this.businessProcessThreadMap = businessProcessThreadMap;
    }
    
    @SuppressWarnings("deprecation")
    @Override
    public void run() {
        try {
            if(jobInstanceOld != null){
                jobInstanceOld.businessProcess(businessData);
            }else if(jobInstance != null){
                jobInstance.businessProcess(businessData);
            }else{
                LOG.error("TASK-PROCESS-JOB: run a business process thread with param=[{}] fail because jobInstance is null:", businessData);
            }
        } catch (Throwable e) {
            LOG.error("TASK-PROCESS-JOB: run a business process thread with param=[{}] exception:", businessData, e);
        } finally {
            completeLock.lock();
            try {
                businessProcessThreadMap.remove(this);
                if (businessProcessThreadMap.isEmpty()) {
                    returnWaitting.countDown();
                }
            } finally {
                completeLock.unlock();
            }
        }
    }
    
}
